package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"sync"
	"time"
	"util"
)

type TaskWait struct {
	Lock     sync.RWMutex
	Task     map[string]*util.TaskObj
	TaskNull chan bool
}

var taskWait = &TaskWait{Task: make(map[string]*util.TaskObj), TaskNull: make(chan bool)}

func main() {
	go taskWait.watching()
	http.HandleFunc("/pass", func(w http.ResponseWriter, r *http.Request) {
		ok := func() bool {
			b, err := ioutil.ReadAll(r.Body)
			if err != nil {
				log.Println(err)
				return false
			}
			task := util.TaskObj{}
			if err = json.Unmarshal(b, &task); err != nil {
				log.Println(err)
				return false
			}
			//修改iptables
			if !changeIptables(&task, "-I") {
				return false
			}
			taskWait.addTask(&task)
			return true
		}()
		w.Write([]byte(fmt.Sprintf("{success:%v}", ok)))
	})
	http.ListenAndServe(":11062", nil)
}

func (t *TaskWait) addTask(task *util.TaskObj) {
	t.Lock.Lock()
	defer t.Lock.Unlock()
	if len(t.Task) == 0 {
		t.TaskNull <- false
	}
	key := fmt.Sprintf("%s_%d", task.AccIp, task.StarTime)
	t.Task[key] = task
}
func (t *TaskWait) removeTask(task *util.TaskObj) {
	t.Lock.Lock()
	defer t.Lock.Unlock()
	log.Println("移除", task.AccIp)
	key := fmt.Sprintf("%s_%d", task.AccIp, task.StarTime)
	delete(t.Task, key)
}

//定时监测
func (t *TaskWait) watching() {
	if len(t.Task) == 0 {
		<-t.TaskNull
	}
	log.Printf("共有%d条记录", len(t.Task))
	for k, task := range (*taskWait).Task {
		log.Println(k, "---", fmt.Sprintf("%+v", task))
		if !time.Unix(task.StarTime, 0).Add(time.Hour * time.Duration(task.AccTime)).After(time.Now()) {
			if changeIptables(task, "-D") {
				t.removeTask(task)
			}
		}
	}

	time.AfterFunc(time.Minute, t.watching)
}

func changeIptables(task *util.TaskObj, Actype string) bool {
	//iptables -I INPUT -p tcp -s ***.***.***.*** -m multiport  --dport 8800,27080,6379 -j ACCEPT
	return util.ExecCommand("iptables", Actype, task.ChainType, "-p", "tcp", "-s", task.AccIp, "-m", "multiport", "--dport", task.AccPORT, "-j", "ACCEPT")
}
